package edu.ptu.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import edu.ptu.acl.common.MyConstants;
import edu.ptu.acl.entity.Acl;
import edu.ptu.acl.entity.Log;
import edu.ptu.acl.entity.Role;
import edu.ptu.acl.entity.RoleUser;
import edu.ptu.acl.exception.ApiException;
import edu.ptu.acl.mapper.AclMapper;
import edu.ptu.acl.mapper.LogMapper;
import edu.ptu.acl.mapper.RoleMapper;
import edu.ptu.acl.mapper.RoleUserMapper;
import edu.ptu.acl.service.ILogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.ptu.acl.service.IRoleAclService;
import edu.ptu.acl.service.IRoleUserService;
import edu.ptu.acl.utils.JsonMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author LinJC
 * @since 2022-03-15
 */
@Service
public class LogServiceImpl extends ServiceImpl<LogMapper, Log> implements ILogService {

    @Resource
    private LogMapper logMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private IRoleUserService roleUserService;
    @Resource
    private IRoleAclService roleAclService;

    @Override
    public void saveRoleUserLog(Long roleId, List<Long> before, List<Long> after) {
        Log log = Log.builder().type(MyConstants.LogType.ROLE_USER.getType())
                .status("0").targetId(roleId).build();
        log.setNewValue(after == null ? "" : JsonMapper.obj2String(after));
        log.setOldValue(before == null ? "" : JsonMapper.obj2String(before));
        logMapper.insert(log);
    }

    @Override
    public void saveRoleAclLog(Long roleId, List<Long> before, List<Long> after) {
        Log log = Log.builder().type(MyConstants.LogType.ROLE_ACL.getType())
                .status("0").targetId(roleId).build();
        log.setNewValue(after == null ? "" : JsonMapper.obj2String(after));
        log.setOldValue(before == null ? "" : JsonMapper.obj2String(before));
        logMapper.insert(log);
    }

    @Override
    public void recover(Long id){
        Log log = logMapper.selectById(id);
        if (log == null){
            throw new ApiException("记录不存在");
        }
        if (StringUtils.equals("1",log.getStatus())){
            throw new ApiException("已恢复过");
        }
        if (StringUtils.equals(log.getType(),MyConstants.LogType.ROLE_USER.getType())){
            Role role = roleMapper.selectById(log.getTargetId());
            if (role == null){
                throw new ApiException("记录不存在");
            }
            List<Long> beforeUserId = JsonMapper.string2Obj(log.getOldValue(), new TypeReference<List<Long>>() {});
//            List<Long> afterUserId = JsonMapper.string2Obj(log.getNewValue(), new TypeReference<List<Long>>() {});
            roleUserService.updateRoleUser(log.getTargetId(),beforeUserId);
            log.setStatus("1");
            logMapper.updateById(log);
//            saveRoleUserLog(log.getTargetId(),afterUserId,beforeUserId);
        }else {
            Role role = roleMapper.selectById(log.getTargetId());
            if (role == null){
                throw new ApiException("记录不存在");
            }
            List<Long> beforeAclId = JsonMapper.string2Obj(log.getOldValue(), new TypeReference<List<Long>>() {});
//            List<Long> afterAclId = JsonMapper.string2Obj(log.getNewValue(), new TypeReference<List<Long>>() {});
            roleAclService.updateRoleAcl(log.getTargetId(),beforeAclId);
            log.setStatus("1");
            logMapper.updateById(log);
//            saveRoleUserLog(log.getTargetId(),afterAclId,beforeAclId);
        }
    }

    @Override
    public Page getLogByCondition(Page page, String fromTime, String toTime, String updator,String type) {
        QueryWrapper<Log> logQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(updator)){
            logQueryWrapper.like("updator",updator);
        }
        if (StringUtils.isNotBlank(type)){
            logQueryWrapper.eq("type",type);
        }
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isNotBlank(fromTime)) {
                logQueryWrapper.ge("update_time",fromTime);
                dateFormat.parse(fromTime);
            }
            if (StringUtils.isNotBlank(toTime)) {
                logQueryWrapper.le("update_time",toTime);
                dateFormat.parse(toTime);
            }
        } catch (Exception e) {
            throw new ApiException("传入的日期格式有问题，正确格式为：yyyy-MM-dd HH:mm:ss");
        }

        logMapper.selectPage(page,logQueryWrapper);

        return page;
    }
}
